<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
    <meta http-equiv="X-UA-Compatible" content="ie=edge,chrome=1">
    <meta name="referrer" content="never">
    <title>函数</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        ul {
            list-style: none;
        }
    </style>
</head>
<body>
    
    <script type="text/javascript">
        // "use strict";
        // 严格模式：1. 所有JS最上方书写 "use strict" 2. 在函数体最上方  "use strict"
        // 开启后：函数中未经声明的变量不可使用；arguments中实参与形参的关系断裂；arguments.callee 方法不可用

        /* 
        函数：N条语句的封装体，用于实现某个功能。简化了代码书写，提高了代码的可阅读性
            创建函数的方式：
                1. 声明函数  function 函数名(){ 函数体 }
                2. 函数表达式   var 函数名 = function(){ 函数体 }
                3. new Function(形参, 函数体)  几乎不使用
                声明函数使用 函数声明提升（带值提升） <--> 函数表达式 变量声明提升

            函数的形参：假想的实参。函数中声明的变量
                形参数 > 实参数：多余的形参值为 undefined
                形参数 < 实参数：多余的实参被忽略，可以在 arguments 中被访问
                传入简单类型与引用类型值：
                    简单类型值作为参数，在函数内部的改变不会影响实参
                    引用类型值作为参数，在函数内部的改变可以影响传入的实参（注意是否是重新赋值）

            
            arguments: 由所有实参组成的伪数组，如果实参有对应的形参，那么arguments中对应实参的位置是形参的映射
                arguments.callee() 调用当前函数，面临淘汰


        */


        function add(a, b, c, d){
            // "use strict";
            a = 20;
            console.log(a);
            arguments[1] = 40;
            console.log(b);
            console.log(c);
            console.log(d);
            console.log(arguments); // [a,b,c,d,6]
            // if(c != 30){
            //     arguments.callee(1,2,30,50,80);
            // }
            f = "函数中未经声明的变量，是全局变量";
        }

        add(1,2,4,5,6);

        console.log(f);
        console.clear();

        var params = {};
        
        function fn(a){
            // a = { name: "李白" };
            a.name = "李白";
        }

        fn(params);
        
        console.log(params); // { name: "李白" }

        console.clear();

        // 函数开始执行时，内部会创建活动对象 AO scope this  AO activation Object函数内部所有的变量组成的对象
        // AO => { 1. 所有的形参  2. 所有声明函数  3. 所有声明变量 }
        function func(num){
            console.log(num);
            
            function num(){
                console.log("aaa");
            }
            
            var num = "hello";
        }

        func(10);

    </script>
</body>
</html>